package cn.yunyichina.provider.pay.service.impl;

import cn.yunyichina.provider.framework.dubbo.service.AlipayService;
import cn.yunyichina.provider.framework.dubbo.service.HymedService;
import cn.yunyichina.provider.framework.dubbo.service.PacityService;
import cn.yunyichina.provider.framework.dubbo.service.WechatPayService;
import cn.yunyichina.provider.iface.entity.alipay.Alipay;
import cn.yunyichina.provider.iface.entity.alipay.AlipayRequest;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.provider.iface.entity.dto.hymed.MedicalCardQueryRequestDTO;
import cn.yunyichina.provider.iface.entity.dto.hymed.MedicalCardQueryResponseDTO;
import cn.yunyichina.provider.iface.entity.dto.hymed.PaymentConsumeRequestDTO;
import cn.yunyichina.provider.iface.entity.dto.hymed.PaymentConsumeResponseDTO;
import cn.yunyichina.provider.iface.entity.dto.pacity.PacityPayRequestDTO;
import cn.yunyichina.provider.iface.entity.dto.pacity.PacityPayResponseDTO;
import cn.yunyichina.provider.iface.entity.dto.pay.*;
import cn.yunyichina.provider.iface.entity.dto.wechat.WechatWebPayRequestDTO;
import cn.yunyichina.provider.iface.entity.dto.wechat.WechatWebPayResponseDTO;
import cn.yunyichina.provider.iface.entity.pay.MchData;
import cn.yunyichina.provider.iface.entity.pay.PayCode;
import cn.yunyichina.provider.iface.entity.pay.notify.UnifiedPayNotifyMessage;
import cn.yunyichina.provider.iface.entity.vo.pay.PacityPayVO;
import cn.yunyichina.provider.pay.constant.Medicare;
import cn.yunyichina.provider.pay.constant.MethodRouter;
import cn.yunyichina.provider.pay.constant.ResponseEnum;
import cn.yunyichina.provider.pay.constant.Wechat;
import cn.yunyichina.provider.pay.entity.PaymentSetting;
import cn.yunyichina.provider.pay.entity.notify.AlipayNotify;
import cn.yunyichina.provider.pay.entity.notify.WechatPayAttach;
import cn.yunyichina.provider.pay.exception.PaySettingNotFoundException;
import cn.yunyichina.provider.pay.executor.PayNotifyExecutor;
import cn.yunyichina.provider.pay.executor.PayNotifyWorker;
import cn.yunyichina.provider.pay.model.vo.WechatWebPayVO;
import cn.yunyichina.provider.pay.service.BasePayService;
import cn.yunyichina.provider.pay.service.NotifyService;
import cn.yunyichina.provider.pay.service.PayService;
import cn.yunyichina.utils.commons.DateUtils;
import cn.yunyichina.utils.commons.RandomUtil;
import cn.yunyichina.utils.constants.Encoding;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.dozer.Dozer;
import cn.yunyichina.utils.json.Jackson;
import cn.yunyichina.utils.security.SignUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.google.common.collect.Maps;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付统一入口
 * Created by Lullaby on 2016/10/14.
 */
@Service
public class PayServiceImpl extends BasePayService implements PayService {

    private static final Logger logger = LoggerFactory.getLogger(PayServiceImpl.class);

    @Resource
    private NotifyService notifyService;

    @Resource
    private PayNotifyExecutor notifyExecutor;

    public ResponseObject unifiedPay(String data) {
        logger.info("PayServiceImpl.unifiedPay.data -> {}", data);
        ResponseObject response = new ResponseObject();

        try {
            Map<String, String> params = JSON.parseObject(data, Map.class);
            String payCode = params.get("pay_code");

            switch (PayCode.valueOf(payCode)) {
                case WXJSAPI: // 微信公众号支付
                    return wechatJsapiPay(params);
                case WXAPP: // 微信APP支付
                    return wechatAppPay(params);
                case WXNATIVE: // 微信原生扫码支付
                    return wechatNativePay(params);
                case WXMICROPAY: // 微信刷卡支付
                    return wechatMicroPay(params);
                case WXWEB: // 微信H5支付
                    return wechatWebPay(params);
                case WXAPPLET: // 微信小程序支付
                    return wechatAppletPay(params);
                case WXMEDICALPAY: // 微信医疗支付
                    return wechatMedicalPay(params);
                case ALIPAYWAP: // 支付宝手机网站支付
                    return alipayWapPay(params);
                case ALIPAYAPP: // 支付宝APP支付
                    return alipayAppPay(params);
                case ALIPAYPREPAY: // 支付宝扫码支付
                    return alipayPrecreatePay(params);
                case ALIPAYBARPAY: // 支付宝条码支付
                    return alipayBarPay(params);
                case ALIPAYWAVEPAY: // 支付宝声波支付
                    return alipayWavePay(params);
                case ALIPAYRECEIPT: // 支付宝收款
                    return alipayReceiptPay(params);
                case ALIPAYMEDICARE: // 支付宝医保WAP支付
                    return alipayMedicareWapPay(params);
                case ALIPAYMEDICAREBARPAY: // 支付宝医保条码付
                    return alipayMedicareBarPay(params);
                case ALIPAYMEDICAREWAVEPAY: // 支付宝医保声波付
                    return alipayMedicareWavePay(params);
                case PACITY: // 平安支付
                    return pacityPay(params);
                case ALIPAYMEDINFOUPLOAD:// 支付宝医疗信息报备(0元医保挂号)
                    return alipayMedInfoUpload(params);
                case HYMEDUNION: // 河源银联一卡通支付
                    return hymedUnionPay(params);
                case ALIPAYMEDWAP: // 支付宝医疗自费WAP支付
                    return alipayMedWapPay(params);
                default:
                    return response.buildResultCodeAndMessage(
                            ResponseEnum.PAY_CODE_UNSUPPORTED.getCode(),
                            ResponseEnum.PAY_CODE_UNSUPPORTED.getMessage()
                    );
            }
        } catch (PaySettingNotFoundException e) {
            logger.error("PayServiceImpl.unifiedPay.PaySettingNotFoundException", e);
            return response.buildResultCodeAndMessage(
                    ResponseEnum.PAY_SETTING_NOT_FOUND.getCode(),
                    ResponseEnum.PAY_SETTING_NOT_FOUND.getMessage()
            );
        } catch (AlipayApiException e) {
            logger.error("PayServiceImpl.unifiedPay.AlipayApiException", e);
            return response.buildResultCodeAndMessage(
                    ResponseEnum.ALIPAY_EXCEPTION.getCode(),
                    ResponseEnum.ALIPAY_EXCEPTION.getMessage()
            );
        } catch (Exception e) {
            logger.error("PayServiceImpl.unifiedPay.Exception", e);
            return response.buildResultCodeAndMessage(
                    ResponseEnum.PAY_EXCEPTION.getCode(),
                    ResponseEnum.PAY_EXCEPTION.getMessage()
            );
        }
    }

    private ResponseObject wechatJsapiPay(Map<String, String> params) throws PaySettingNotFoundException {
        if (!checkWechatJsapiPayParameters(params)) return invalidPayParamsResponseObject();

        Map<String, String> parameters = buildWechatJsapiOrAppletPayParameters(params);
        String request = JSON.toJSONString(parameters);
        logger.info("PayServiceImpl.wechatJsapiPay.request -> {}", request);

        ResponseObject response = WechatPayService.callUnderlineFromInternalObject(MethodRouter.WECHAT_PAY_JSAPI, request);
        logger.info("PayServiceImpl.wechatJsapiPay.response -> {}", JSON.toJSONString(response));

        return response;
    }

    private ResponseObject wechatAppPay(Map<String, String> params) throws PaySettingNotFoundException {
        if (!checkWechatAppPayParameters(params)) return invalidPayParamsResponseObject();

        Map<String, String> parameters = buildWechatAppPayParameters(params);
        String request = JSON.toJSONString(parameters);
        logger.info("PayServiceImpl.wechatAppPay.request -> {}", request);

        ResponseObject response = WechatPayService.callUnderlineFromInternalObject(MethodRouter.WECHAT_PAY_APP, request);
        logger.info("PayServiceImpl.wechatAppPay.response -> {}", JSON.toJSONString(response));

        return response;
    }

    private ResponseObject wechatNativePay(Map<String, String> params) throws PaySettingNotFoundException {
        if (!checkWechatNativePayParameters(params)) return invalidPayParamsResponseObject();

        Map<String, String> parameters = buildWechatNativePayParameters(params);
        String request = JSON.toJSONString(parameters);
        logger.info("PayServiceImpl.wechatNativePay.request -> {}", request);

        ResponseObject response = WechatPayService.callUnderlineFromInternalObject(MethodRouter.WECHAT_PAY_NATIVE, request);
        logger.info("PayServiceImpl.wechatNativePay.response -> {}", JSON.toJSONString(response));

        return response;
    }

    private ResponseObject wechatMicroPay(Map<String, String> params) throws Exception {
        if (checkWechatMicroPayParameters(params)) return invalidPayParamsResponseObject();

        WechatMicroPayRequestDTO requestDTO = buildWechatMicroPayParameters(params);
        logger.info("PayServiceImpl.wechatMicroPay.requestDTO -> {}", JsonUtils.toJsonString(requestDTO));

        ResCommon<WechatMicroPayResponseDTO> response = WechatPayService.getWechatPayClient().microWechatPay(requestDTO);
        logger.info("PayServiceImpl.wechatMicroPay.response -> {}", JsonUtils.toJsonString(response));

        if (response.isSuccess()) {
            WechatMicroPayResponseDTO responseDTO = response.getResult();
            if (responseDTO.isResultCodeSuccess()) {
                return wechatMicroPaySucceed(params, responseDTO);
            } else {
                return wechatMicroPayProcessing(params);
            }
        }

        return new ResponseObject(response.getResultCode(), response.getResultMessage(), response.getResult());
    }

    private ResponseObject wechatMicroPaySucceed(Map<String, String> params, WechatMicroPayResponseDTO responseDTO) {
        Map<String, String> notifyParams = Maps.newHashMap();
        WechatPayAttach attach = new WechatPayAttach();
        attach.setPayCode(params.get("pay_code"));
        notifyParams.put("attach", JsonUtils.toJsonString(attach));
        notifyParams.put("appid", responseDTO.getAppid());
        notifyParams.put("out_trade_no", responseDTO.getOutTradeNo());
        notifyParams.put("total_fee", responseDTO.getTotalFee());
        notifyParams.put("transaction_id", responseDTO.getTransactionId());
        notifyParams.put("openid", responseDTO.getOpenid());
        notifyParams.put("time_end", responseDTO.getTimeEnd());

        notifyService.doOrdinaryWechatPayNotify(notifyParams, null);

        return new ResponseObject().buildResultObject(responseDTO);
    }

    private ResponseObject wechatMicroPayProcessing(Map<String, String> params) throws Exception {
        WechatOrderQueryResponseDTO queryResponseDTO = queryWechatMicroPay(params);

        if (queryResponseDTO != null && Wechat.TRADE_STATE.SUCCESS == Wechat.TRADE_STATE.valueOf(queryResponseDTO.getTradeState())) {
            WechatMicroPayResponseDTO payResponseDTO = Jackson.fromObject(queryResponseDTO, WechatMicroPayResponseDTO.class);
            return wechatMicroPaySucceed(params, payResponseDTO);
        }

        WechatOrderReverseResponseDTO reverseResponseDTO = reverseWechatMicroPay(params);
        if (reverseResponseDTO != null) {
            return new ResponseObject(ResponseEnum.ORDER_REVERSED.getCode(), ResponseEnum.ORDER_REVERSED.getMessage());
        }

        return new ResponseObject(ResponseEnum.PAY_EXCEPTION.getCode(), ResponseEnum.PAY_EXCEPTION.getMessage());
    }

    private WechatOrderReverseResponseDTO reverseWechatMicroPay(Map<String, String> params) throws Exception {
        WechatOrderReverseRequestDTO reverseRequestDTO = buildReverseWechatOrderParameters(params);

        int times = 0, count = 5, millis = 1000;

        Thread.sleep(millis);
        do {
            try {
                logger.info("PayServiceImpl.reverseWechatMicroPay.reverse.times -> {}", times);

                ResCommon<WechatOrderReverseResponseDTO> reverseResponse = WechatPayService.getWechatPayClient().reverseWechatOrder(reverseRequestDTO);
                logger.info("PayServiceImpl.reverseWechatMicroPay.reverseResponse -> {}", Jackson.toJson(reverseResponse));

                if (reverseResponse.isSuccess()) {
                    WechatOrderReverseResponseDTO reverseResponseDTO = reverseResponse.getResult();
                    if (reverseResponseDTO.isResultCodeSuccess()) {
                        return reverseResponseDTO;
                    }
                }

                times++;

                if (times == count) {
                    break;
                }

                Thread.sleep(millis);
            } catch (Exception e) {
                logger.error("PayServiceImpl.reverseWechatMicroPay.Exception", e);
            }
        } while (times < count);

        return null;
    }

    private WechatOrderQueryResponseDTO queryWechatMicroPay(Map<String, String> params) throws Exception {
        WechatOrderQueryRequestDTO queryRequestDTO = buildQueryWechatOrderParameters(params);

        int times = 0, count = 6, millis = 5000;

        Thread.sleep(millis);
        do {
            try {
                logger.info("PayServiceImpl.reverseWechatMicroPay.query.times -> {}", times);

                ResCommon<WechatOrderQueryResponseDTO> queryResponse = WechatPayService.getWechatPayClient().queryWechatOrder(queryRequestDTO);
                logger.info("PayServiceImpl.wechatMicroPayProcessing.queryResponse -> {}", Jackson.toJson(queryResponse));

                if (queryResponse.isSuccess()) {
                    WechatOrderQueryResponseDTO responseDTO = queryResponse.getResult();
                    if (Wechat.TRADE_STATE.SUCCESS.toString().equals(responseDTO.getTradeState())) {
                        return queryResponse.getResult();
                    }
                }

                times++;

                if (times == count) {
                    break;
                }

                Thread.sleep(millis);
            } catch (Exception e) {
                logger.error("PayServiceImpl.queryWechatMicroPay.Exception", e);
            }
        } while (times < count);

        return null;
    }

    private ResponseObject wechatWebPay(Map<String, String> params)
            throws PaySettingNotFoundException, UnsupportedEncodingException {
        if (checkWechatWebPayParameters(params)) return invalidPayParamsResponseObject();

        ResponseObject response = new ResponseObject();

        WechatWebPayRequestDTO rpcRequest = buildWechatWebPayParameters(params);
        logger.info("PayServiceImpl.wechatWebPay.rpcRequest -> {}", JSON.toJSONString(rpcRequest));

        ResCommon<WechatWebPayResponseDTO> rpcResponse = WechatPayService.getWechatPayClient().webPay(rpcRequest);
        logger.info("PayServiceImpl.wechatWebPay.rpcResponse -> {}", JSON.toJSONString(rpcResponse));

        if (response.isSuccess()) {
            WechatWebPayVO payVO = new WechatWebPayVO();
            WechatWebPayResponseDTO responseDTO = rpcResponse.getResult();
            if (responseDTO.isResultCodeSuccess()) {
                if (responseDTO.isResultCodeSuccess()) {
                    String returnUrl = params.get("return_url");
                    if (!StringUtils.isEmpty(returnUrl)) {
                        String mwebUrl = responseDTO.getMwebUrl()
                                .concat("&redirect_url=")
                                .concat(URLEncoder.encode(returnUrl, Encoding.UTF8));
                        logger.info("PayServiceImpl.wechatWebPay.mwebUrl -> ", mwebUrl);
                        responseDTO.setMwebUrl(mwebUrl);
                    }

                    Dozer.copy(responseDTO, payVO);
                    response.setResultObject(payVO);
                } else {
                    response.fail();
                    payVO.setErrcode(responseDTO.getErrCode());
                    payVO.setErrmsg(responseDTO.getErrCodeDes());
                }
            } else {
                response.fail();
                payVO.setErrcode(responseDTO.getReturnCode());
                payVO.setErrmsg(responseDTO.getReturnMsg());
            }
            response.setResultObject(payVO);
        } else {
            response.setResultCodeAndMessage(ResponseEnum.PAY_FAILURE.getCode(), ResponseEnum.PAY_FAILURE.getMessage());
        }

        return response;
    }

    private ResponseObject wechatAppletPay(Map<String, String> params) throws PaySettingNotFoundException {
        if (!checkWechatAppletPayParameters(params)) return invalidPayParamsResponseObject();

        Map<String, String> parameters = buildWechatJsapiOrAppletPayParameters(params);
        String request = JSON.toJSONString(parameters);
        logger.info("PayServiceImpl.wechatAppletPay.request -> {}", request);

        ResponseObject response = WechatPayService.callUnderlineFromInternalObject(MethodRouter.WECHAT_WXAPPLET_PAY, request);
        logger.info("PayServiceImpl.wechatAppletPay.response -> {}", JSON.toJSONString(response));

        return response;
    }

    private ResponseObject wechatMedicalPay(Map<String, String> params) throws PaySettingNotFoundException {
        if (!checkWechatMedicalPayBaseParameters(params)) return invalidPayParamsResponseObject();
        ResponseObject response = new ResponseObject();

        String isInsurance = params.get("is_insurance");
        switch (Medicare.Insurance.valueOf(isInsurance)) {
            case YEP:
                return wechatMedicalMedicarePay(params);
            case NOPE:
                return wechatMedicalSelfPay(params);
            default:
                return response.buildResultCodeAndMessage(
                        ResponseEnum.UNSUPPORTED.getCode(),
                        ResponseEnum.UNSUPPORTED.getMessage()
                );
        }
    }

    private ResponseObject wechatMedicalMedicarePay(Map<String, String> params) throws PaySettingNotFoundException {
        if (!checkWechatMedicalMedicarePayParameters(params)) return invalidPayParamsResponseObject();
        ResponseObject response = new ResponseObject();

        String appid = params.get("app_id");
        String orgCode = params.get("hospital_code");
        String payCode = params.get("pay_code");
        int payMode = getPayModeByPayCode(payCode);

        PaymentSetting parentSetting = this.getPaymentSetting(appid);
        if (parentSetting == null) throw new PaySettingNotFoundException("ParentSetting not found");
        logger.info("PayServiceImpl.wechatMedicalMedicarePay.parentSetting -> {}", JsonUtils.toJsonString(parentSetting));

        PaymentSetting subSetting = this.getSubPaymentSettingByParentIdAndOrgCodeAndPayMode(parentSetting.getId(), orgCode, payMode);
        if (subSetting == null) throw new PaySettingNotFoundException("SubSetting not found");
        logger.info("PayServiceImpl.wechatMedicalMedicarePay.subSetting -> {}", JsonUtils.toJsonString(subSetting));

        String apiSecret = parentSetting.getMedicarePayKey();

        String accessToken = getWechatMedicalPayAccessToken(
                buildMedicalPayAccessTokenParametersMap(
                        subSetting.getPayAppId(),
                        parentSetting.getPayAppId(),
                        parentSetting.getSecretKey()
                )
        );
        logger.info("PayServiceImpl.wechatMedicalMedicarePay.accessToken -> {}", accessToken);

        if (StringUtils.isEmpty(accessToken))
            return response.buildResultCodeAndMessage(
                    ResponseEnum.WECHAT_ACCESS_TOKEN_FAILURE.getCode(),
                    ResponseEnum.WECHAT_ACCESS_TOKEN_FAILURE.getMessage()
            );

        String openid = params.get("openid");
        String username = params.get("user_name");
        String idcard = params.get("card_no");

        if (!wechatMedicalPayVerifyName(accessToken, apiSecret, openid, username, idcard))
            return response.buildResultCodeAndMessage(
                    ResponseEnum.WECHAT_VERIFY_NAME_FAILURE.getCode(),
                    ResponseEnum.WECHAT_VERIFY_NAME_FAILURE.getMessage()
            );

        params.put("access_token", accessToken);
        params.put("api_secret", apiSecret);

        params.put("appid", parentSetting.getPayAppId());
        params.put("mch_id", parentSetting.getMerchantAccount());
        params.put("sub_appid", subSetting.getPayAppId());
        params.put("sub_mch_id", subSetting.getMerchantAccount());

        Map<String, String> wechatMedicalPayRequestMap = buildWechatMedicalMedicarePayParameters(params);
        String wechatMedicalPayRequest = JsonUtils.toJsonString(wechatMedicalPayRequestMap);
        logger.info("PayServiceImpl.wechatMedicalMedicarePay.wechatMedicalPayRequest -> {}", wechatMedicalPayRequest);

        ResponseObject wechatMedicalPayResponse = WechatPayService.callUnderlineFromInternalObject(
                MethodRouter.WECHAT_PAY_MEDICAL, wechatMedicalPayRequest
        );
        logger.info("PayServiceImpl.wechatMedicalMedicarePay.wechatMedicalPayResponse -> {}", JsonUtils.toJsonString(wechatMedicalPayResponse));

        if (!wechatMedicalPayResponse.isSuccess())
            return response.buildResultCodeAndMessageAndResult(
                    ResponseEnum.PAY_FAILURE.getCode(),
                    ResponseEnum.PAY_FAILURE.getMessage(),
                    wechatMedicalPayResponse.getResultObject()
            );

        return response.buildResultCodeAndMessageAndResult(
                wechatMedicalPayResponse.getResultCode(),
                wechatMedicalPayResponse.getResultMessage(),
                wechatMedicalPayResponse.getResultObject()
        );
    }

    private ResponseObject wechatMedicalSelfPay(Map<String, String> params) throws PaySettingNotFoundException {
        String appid = params.get("app_id");
        String orgCode = params.get("hospital_code");
        String payCode = params.get("pay_code");
        int payMode = getPayModeByPayCode(payCode);

        PaymentSetting parentSetting = this.getPaymentSetting(appid);
        if (parentSetting == null) throw new PaySettingNotFoundException("ParentSetting not found");
        logger.info("PayServiceImpl.wechatMedicalSelfPay.parentSetting -> {}", JsonUtils.toJsonString(parentSetting));

        PaymentSetting subSetting = this.getSubPaymentSettingByParentIdAndOrgCodeAndPayMode(parentSetting.getId(), orgCode, payMode);
        if (subSetting == null) throw new PaySettingNotFoundException("SubSetting not found");
        logger.info("PayServiceImpl.wechatMedicalSelfPay.subSetting -> {}", JsonUtils.toJsonString(subSetting));

        String accessToken = getWechatMedicalPayAccessToken(
                buildMedicalPayAccessTokenParametersMap(
                        subSetting.getPayAppId(),
                        parentSetting.getPayAppId(),
                        parentSetting.getSecretKey()
                )
        );
        logger.info("PayServiceImpl.wechatMedicalSelfPay.accessToken -> {}", accessToken);

        if (StringUtils.isEmpty(accessToken))
            return new ResponseObject().buildResultCodeAndMessage(
                    ResponseEnum.WECHAT_ACCESS_TOKEN_FAILURE.getCode(),
                    ResponseEnum.WECHAT_ACCESS_TOKEN_FAILURE.getMessage()
            );

        HashMap<String, String> payParams = new HashMap<>();
        payParams.putAll(params);
        payParams.put("access_token", accessToken);
        payParams.put("appid", parentSetting.getPayAppId());
        payParams.put("mch_id", parentSetting.getMerchantAccount());
        payParams.put("sub_appid", subSetting.getPayAppId());
        payParams.put("sub_mch_id", subSetting.getMerchantAccount());
        payParams.put("api_secret", parentSetting.getMedicarePayKey());

        Map<String, String> wechatMedicalPayRequestMap = buildWechatMedicalSelfPayParameters(payParams);
        String wechatMedicalPayRequest = JsonUtils.toJsonString(wechatMedicalPayRequestMap);
        logger.info("PayServiceImpl.wechatMedicalSelfPay.wechatMedicalPayRequest -> {}", wechatMedicalPayRequest);

        ResponseObject wechatMedicalPayResponse = WechatPayService.callUnderlineFromInternalObject(
                MethodRouter.WECHAT_PAY_MEDICAL, wechatMedicalPayRequest
        );
        logger.info("PayServiceImpl.wechatMedicalSelfPay.wechatMedicalPayResponse -> {}", JsonUtils.toJsonString(wechatMedicalPayResponse));

        if (wechatMedicalPayResponse.isSuccess())
            return new ResponseObject().buildResultCodeAndMessageAndResult(
                    wechatMedicalPayResponse.getResultCode(),
                    wechatMedicalPayResponse.getResultMessage(),
                    wechatMedicalPayResponse.getResultObject()
            );

        return new ResponseObject().buildResultCodeAndMessageAndResult(
                ResponseEnum.PAY_FAILURE.getCode(),
                ResponseEnum.PAY_FAILURE.getMessage(),
                wechatMedicalPayResponse.getResultObject()
        );
    }

    private boolean wechatMedicalPayVerifyName(String accessToken, String apiSecret, String openid, String username, String idcard) {
        logger.info("PayServiceImpl.wechatMedicalPayVerifyName.params -> {}, {}, {}, {}", accessToken, openid, username, idcard);

        try {
            String verifyNameParamsJson = JsonUtils.toJsonString(buildWechatVerifyNameParameters(accessToken, apiSecret, openid, username, idcard));
            logger.info("PayServiceImpl.wechatMedicalPayVerifyName.verifyNameParamsJson -> {}", verifyNameParamsJson);
            ResponseObject verifyNameResponse = WechatPayService.callUnderlineFromInternalObject(
                    MethodRouter.WECHAT_MEDICAL_VERIFY_NAME, verifyNameParamsJson
            );

            logger.info("PayServiceImpl.wechatMedicalPayVerifyName.verifyNameResponse -> {}", JsonUtils.toJsonString(verifyNameResponse));
            if (verifyNameResponse.isSuccess()) {
                return true;
            }
        } catch (Exception e) {
            logger.error("PayServiceImpl.wechatMedicalPayVerifyName.Exception", e);
        }

        return false;
    }

    private ResponseObject alipayWapPay(Map<String, String> params) throws PaySettingNotFoundException {
        if (checkAlipayWapPayParameters(params)) return invalidPayParamsResponseObject();

        Map<String, String> request = buildAlipayWapPayParameters(params);
        String parameters = JSON.toJSONString(request);
        logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.wap] input parameters -> {}", parameters);

        ResponseObject response = AlipayService.callUnderlineFromInternalObject(MethodRouter.ALIPAY_TRADE_WAP, parameters);
        logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.wap] output parameters -> {}", JSON.toJSONString(response));

        return response;
    }

    private ResponseObject alipayAppPay(Map<String, String> params) throws PaySettingNotFoundException {
        if (!checkAlipayAppPayParameters(params)) return invalidPayParamsResponseObject();

        Map<String, String> parameters = buildAlipayAppPayParameters(params);
        String request = JSON.toJSONString(parameters);
        logger.info("PayServiceImpl.alipayAppPay.request -> {}", request);

        ResponseObject response = AlipayService.callUnderlineFromInternalObject(MethodRouter.ALIPAY_TRADE_APP, request);
        logger.info("PayServiceImpl.alipayAppPay.response -> {}", JSON.toJSONString(response));

        return response;
    }

    private ResponseObject alipayPrecreatePay(Map<String, String> params) throws PaySettingNotFoundException {
        if (!checkAlipayPrecreatePayParameters(params)) return invalidPayParamsResponseObject();

        Map<String, String> request = buildAlipayPrecreatePayParameters(params);
        String parameters = JSON.toJSONString(request);
        logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.precreate] input parameters -> {}", parameters);

        ResponseObject response = AlipayService.callUnderlineFromInternalObject(MethodRouter.ALIPAY_TRADE_PRECREATE, parameters);
        logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.precreate] output parameters -> {}", JSON.toJSONString(response));

        return response;
    }

    private ResponseObject alipayBarPay(Map<String, String> params) throws Exception {
        if (checkAlipayFacePayParameters(params)) return invalidPayParamsResponseObject();

        AlipayBarPayRequestDTO requestDTO = buildAlipayBarPayRequestDTO(params);
        logger.info("PayServiceImpl.alipayBarPay.requestDTO -> {}", Jackson.toJson(requestDTO));

        ResCommon<AlipayBarPayResponseDTO> response = AlipayService.getAlipayClient().alipayBarPay(requestDTO);
        logger.info("PayServiceImpl.alipayBarPay.response -> {}", Jackson.toJson(response));

        if (response.isSuccess()) {
            AlipayBarPayResponseDTO responseDTO = response.getResult();
            if (Alipay.SUCCESS_CODE.equals(responseDTO.getCode())) {
                return alipayBarPaySucceed(params, responseDTO);
            } else {
                return alipayBarPayProcessing(params);
            }
        }

        return new ResponseObject(response.getResultCode(), response.getResultMessage(), response.getResult());
    }

    private ResponseObject alipayBarPaySucceed(Map<String, String> map, AlipayBarPayResponseDTO responseDTO) {
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("pay_code", map.get("pay_code"));
        params.put("app_id", map.get("app_id"));
        params.put("trade_status", String.valueOf(AlipayNotify.TradeStatus.TRADE_SUCCESS));
        params.put("buyer_user_id", responseDTO.getBuyerUserId());
        params.put("out_trade_no", responseDTO.getOutTradeNo());
        params.put("trade_no", responseDTO.getTradeNo());
        params.put("gmt_payment", responseDTO.getGmtPayment());
        params.put("total_amount", responseDTO.getTotalAmount());
        params.put("receipt_amount", responseDTO.getReceiptAmount());

        UnifiedPayNotifyMessage unifiedMessage = notifyService.buildAlipayUnifiedMessage(params);
        notifyExecutor.execute(new PayNotifyWorker(unifiedMessage, null));

        return new ResponseObject().buildResultObject(responseDTO);
    }

    private ResponseObject alipayBarPayProcessing(Map<String, String> params) throws Exception {
        AlipayOrderQueryResponseDTO queryResponseDTO = queryAlipayBarPay(params);

        if (queryResponseDTO != null) {
            AlipayBarPayResponseDTO payResponseDTO = Jackson.fromObject(queryResponseDTO.getAlipayTradeQueryResponse(), AlipayBarPayResponseDTO.class);
            return alipayBarPaySucceed(params, payResponseDTO);
        }

        AlipayOrderCancelResponseDTO cancelResponseDTO = cancelAlipayBarPay(params);
        if (cancelResponseDTO != null) {
            return new ResponseObject(ResponseEnum.ORDER_REVERSED.getCode(), ResponseEnum.ORDER_REVERSED.getMessage());
        }

        return new ResponseObject(ResponseEnum.PAY_EXCEPTION.getCode(), ResponseEnum.PAY_EXCEPTION.getMessage());
    }

    private AlipayOrderCancelResponseDTO cancelAlipayBarPay(Map<String, String> params) throws Exception {
        AlipayOrderCancelRequestDTO cancelRequestDTO = buildCancelAlipayOrderParameters(params);

        int times = 0, count = 5, millis = 1000;

        Thread.sleep(millis);
        do {
            try {
                logger.info("PayServiceImpl.cancelAlipayBarPay.cancel.times -> {}", times);

                ResCommon<AlipayOrderCancelResponseDTO> cancelResponse = AlipayService.getAlipayClient().cancelAlipayOrder(cancelRequestDTO);
                logger.info("PayServiceImpl.cancelAlipayBarPay.cancelResponse -> {}", Jackson.toJson(cancelResponse));

                if (cancelResponse.isSuccess()) {
                    AlipayOrderCancelResponseDTO cancelResponseDTO = cancelResponse.getResult();
                    if (Alipay.SUCCESS_CODE.equals(cancelResponseDTO.getAlipayTradeCancelResponse().getCode())) {
                        return cancelResponseDTO;
                    }
                }

                times++;

                if (times == count) {
                    break;
                }

                Thread.sleep(millis);
            } catch (Exception e) {
                logger.error("PayServiceImpl.cancelAlipayBarPay.Exception", e);
            }
        } while (times < count);

        return null;
    }

    private AlipayOrderQueryResponseDTO queryAlipayBarPay(Map<String, String> params) throws Exception {
        AlipayOrderQueryRequestDTO queryRequestDTO = buildQueryAlipayOrderParameters(params);

        int times = 0, count = 6, millis = 5000;

        Thread.sleep(millis);
        do {
            try {
                logger.info("PayServiceImpl.queryAlipayBarPay.query.times -> {}", times);

                ResCommon<AlipayOrderQueryResponseDTO> queryResponse = AlipayService.getAlipayClient().queryAlipayOrder(queryRequestDTO);
                logger.info("PayServiceImpl.queryAlipayBarPay.queryResponse -> {}", Jackson.toJson(queryResponse));

                if (queryResponse.isSuccess()) {
                    AlipayOrderQueryResponseDTO responseDTO = queryResponse.getResult();
                    if (Alipay.TradeStatus.TRADE_SUCCESS == responseDTO.getAlipayTradeQueryResponse().getTradeStatus()) {
                        return responseDTO;
                    }
                }

                times++;

                if (times == count) {
                    break;
                }

                Thread.sleep(millis);
            } catch (Exception e) {
                logger.error("PayServiceImpl.queryAlipayBarPay.Exception", e);
            }
        } while (times < count);

        return null;
    }

    private ResponseObject alipayWavePay(Map<String, String> params) throws PaySettingNotFoundException {
        if (checkAlipayFacePayParameters(params)) return invalidPayParamsResponseObject();

        Map<String, String> request = buildAlipayFacePayParameters(params);
        String parameters = JSON.toJSONString(request);
        logger.info("PayServiceImpl.alipayWavePay.request -> {}", parameters);

        ResponseObject response = AlipayService.callUnderlineFromInternalObject(MethodRouter.ALIPAY_TRADE_FACE, parameters);
        logger.info("PayServiceImpl.alipayWavePay.response -> {}", JSON.toJSONString(response));

        if (response.isSuccess()) {
            Map<String, String> responseMap = JsonUtils.parseObject(response.getResultObject(), Map.class);
            Map<String, String> notifyMap = buildAlipaySyncNotifyParameters(params, request, responseMap);
            String notifyParams = JsonUtils.toJsonString(notifyMap);
            logger.info("PayServiceImpl.alipayWavePay.notifyParams -> {}", notifyParams);

            notifyService.alipayNotify(notifyParams);
        }

        return response;
    }

    private ResponseObject alipayReceiptPay(Map<String, String> params) throws PaySettingNotFoundException {
        logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.receipt] params -> {}", JsonUtils.toJsonString(params));
        return new ResponseObject().buildResultCodeAndMessage(
                ResponseEnum.UNSUPPORTED.getCode(),
                ResponseEnum.UNSUPPORTED.getMessage()
        );
    }

    private ResponseObject alipayMedicareWapPay(Map<String, String> params)
            throws PaySettingNotFoundException, AlipayApiException, UnsupportedEncodingException {
        if (!checkAlipayMedicarePayParameters(params)) return invalidPayParamsResponseObject();

        String appId = params.get("app_id");
        PaymentSetting paymentSetting = this.getPaymentSetting(appId);
        String signType = "RSA";
        if (paymentSetting.getPayPublicKey().length() > 256) {
            signType = "RSA2";
        }

        Map<String, String> authParamsMap = new HashMap<>();
        authParamsMap.put("app_id", appId);
        authParamsMap.put("auth_code", params.get("auth_code"));
        authParamsMap.put("public_key", paymentSetting.getPublicKey());
        authParamsMap.put("private_key", paymentSetting.getPrivateKey());
        authParamsMap.put("sign_type", signType);

        String authParameters = JsonUtils.toJsonString(authParamsMap);
        logger.info("PayServiceImpl.unifiedPay.ALIPAYMEDICARE.authParameters -> {}", authParameters);
        ResponseObject authResponse = AlipayService.callUnderlineFromInternalObject(MethodRouter.ALIPAY_ACCESS_TOKEN, authParameters);
        logger.info("PayServiceImpl.unifiedPay.ALIPAYMEDICARE.authResponse -> {}", JsonUtils.toJsonString(authResponse));

        if (!authResponse.isSuccess())
            return authResponse.buildResultCodeAndMessage(
                    ResponseEnum.OPENID_ALIPAY_EXCEPTION.getCode(),
                    ResponseEnum.OPENID_ALIPAY_EXCEPTION.getMessage()
            );

        Map authMap = (Map) authResponse.getResultObject();
        params.put("auth_token", (String) authMap.get("access_token"));

        Map<String, String> request = buildAlipayMedicarePayParameters(params, paymentSetting);
        logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.medicare] request -> {}", request);

        String payUrl = assembleAlipayMedicarePayUrl(request);
        logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.medicare] payUrl -> {}", payUrl);

        Map<String, String> result = new HashMap<>();
        result.put("pay_url", payUrl);

        return new ResponseObject().buildResultObject(result);
    }

    private ResponseObject alipayMedicareBarPay(Map<String, String> params) throws PaySettingNotFoundException {
        if (!checkAlipayMedicareFacePayParameters(params)) return invalidPayParamsResponseObject();

        Map<String, String> request = buildAlipayMedicareFacePayParameters(params);
        String parameters = JSON.toJSONString(request);
        logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.medicare.barpay] input parameters -> {}", parameters);

        ResponseObject response = AlipayService.callUnderlineFromInternalObject(MethodRouter.ALIPAY_TRADE_FACE, parameters);
        logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.medicare.barpay] output parameters -> {}", JSON.toJSONString(response));

        if (response.isSuccess()) {
            Map<String, String> responseMap = JsonUtils.parseObject(response.getResultObject(), Map.class);
            logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.medicare.barpay] responseMap -> {}", responseMap);

            Map<String, String> notifyMap = buildAlipaySyncNotifyParameters(params, request, responseMap);
            logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.medicare.barpay] notifyMap -> {}", notifyMap);

            String notifyParams = JsonUtils.toJsonString(notifyMap);
            logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.medicare.barpay] notifyParams -> {}", notifyParams);
            notifyService.alipayNotify(notifyParams);
        }

        return response;
    }

    private ResponseObject alipayMedicareWavePay(Map<String, String> params) throws PaySettingNotFoundException {
        if (!checkAlipayMedicareFacePayParameters(params)) return invalidPayParamsResponseObject();

        Map<String, String> request = buildAlipayMedicareFacePayParameters(params);
        String parameters = JSON.toJSONString(request);
        logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.medicare.wavepay] input parameters -> {}", parameters);

        ResponseObject response = AlipayService.callUnderlineFromInternalObject(MethodRouter.ALIPAY_TRADE_FACE, parameters);
        logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.medicare.wavepay] output parameters -> {}", JSON.toJSONString(response));

        if (response.isSuccess()) {
            Map<String, String> responseMap = JsonUtils.parseObject(response.getResultObject(), Map.class);
            logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.medicare.wavepay] responseMap -> {}", responseMap);

            Map<String, String> notifyMap = buildAlipaySyncNotifyParameters(params, request, responseMap);
            logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.medicare.wavepay] notifyMap -> {}", notifyMap);

            String notifyParams = JsonUtils.toJsonString(notifyMap);
            logger.info("PayServiceImpl.unifiedPay.[yyt.pay.alipay.trade.medicare.wavepay] notifyParams -> {}", notifyParams);

            notifyService.alipayNotify(notifyParams);
        }

        return response;
    }

    private ResponseObject pacityPay(Map<String, String> params) throws Exception {
        if (!checkPacityPayParameters(params)) return invalidPayParamsResponseObject();

        ResponseObject response = new ResponseObject();

        PacityPayRequestDTO requestDTO = buildPacityPayRequestDTO(params);
        logger.info("PayServiceImpl.pacityPay.requestDTO -> {}", JSON.toJSONString(requestDTO));

        ResCommon<PacityPayResponseDTO> payResponse = PacityService.getPacityClient().doPacityPay(requestDTO);
        logger.info("PayServiceImpl.pacityPay.payResponse -> {}", JSON.toJSONString(payResponse));

        if (payResponse.isSuccess()) {
            PacityPayResponseDTO responseDTO = payResponse.getResult();

            if (responseDTO.isReturnCodeSuccess() && responseDTO.isResultCodeSuccess()) {
                PacityPayVO pacityPayVO = new PacityPayVO();
                pacityPayVO.setPlatMchId(responseDTO.getPlatMchId());
                pacityPayVO.setPrepayTradeNo(responseDTO.getPrepayTradeNo());
                pacityPayVO.setNonceStr(RandomUtil.getRandomALLChar(32));
                pacityPayVO.setSign(SignUtil.pacitySign(Dozer.convert(pacityPayVO, Map.class), requestDTO.getPrivateKey()));
                logger.info("PayServiceImpl.pacityPay.pacityPayVO -> {}", JSON.toJSONString(pacityPayVO));

                response.setResultObject(pacityPayVO);
            } else {
                response.setResultCodeAndMessageAndResult(
                        ResponseEnum.PACITY_PAY_FAIL.getCode(),
                        ResponseEnum.PACITY_PAY_FAIL.getMessage(),
                        responseDTO
                );
            }
        } else {
            response.setResultCodeAndMessage(payResponse.getResultCode(), payResponse.getResultMessage());
        }

        return response;
    }

    private ResponseObject alipayMedInfoUpload(Map<String, String> params) throws PaySettingNotFoundException {
        if (!checkAlipayMedInfoUploadParameters(params)) return invalidPayParamsResponseObject();

        AlipayRequest alipayRequest = buildAlipayMedInfoUploadRequest(params);
        logger.info("PayServiceImpl.alipayMedInfoUpload.alipayRequest -> {}", JSON.toJSON(alipayRequest));

        ResCommon<AlipayMedInfoUploadResponseDTO> alipayResponse = AlipayService.getAlipayClient().alipayMedInfoUpload(alipayRequest);
        logger.info("PayServiceImpl.alipayMedInfoUpload.alipayResponse -> {}", JSON.toJSON(alipayResponse));

        ResponseObject response = new ResponseObject();

        if (alipayResponse.isSuccess()) {
            AlipayMedInfoUploadResponseDTO responseDTO = alipayResponse.getResult();
            response.setResultObject(responseDTO);

            UnifiedPayNotifyMessage unifiedMessage = buildAlipayMedInfoUploadSyncUnifiedMessage(params, responseDTO);
            notifyExecutor.execute(new PayNotifyWorker(unifiedMessage));
        } else {
            response.setResultCodeAndMessage(alipayResponse.getResultCode(), alipayResponse.getResultMessage());
        }

        return response;
    }

    private ResponseObject hymedUnionPay(Map<String, String> params) throws PaySettingNotFoundException {
        if (!checkHyMedUnionParameters(params)) return invalidPayParamsResponseObject();

        String appCode = params.get("app_code");
        String orgCode = params.get("org_code");
        String payCode = params.get("pay_code");
        short payMode = (short) getPayModeByPayCode(payCode);
        String insuranceLoginName = params.get("insurance_login_name");

        MedicalCardQueryRequestDTO queryRequestDTO = new MedicalCardQueryRequestDTO();
        queryRequestDTO.setAccount(insuranceLoginName);
        queryRequestDTO.setAppCode(appCode);
        queryRequestDTO.setOrgCode(orgCode);
        queryRequestDTO.setPayCode(payCode);

        ResCommon<MedicalCardQueryResponseDTO> cardQueryResponse = HymedService.getHyMedClient().queryMedicareCard(queryRequestDTO);
        logger.info("PayServiceImpl.hymedUnionPay.cardQueryResponse -> {}", JSON.toJSONString(cardQueryResponse));
        if (!cardQueryResponse.isSuccess()) {
            return new ResponseObject().buildResultCodeAndMessageAndResult(
                    cardQueryResponse.getResultCode(),
                    cardQueryResponse.getResultMessage(),
                    cardQueryResponse.getResult()
            );
        }

        PaymentSetting paymentSetting = getPaymentSetting(appCode, orgCode, payMode);
        MedicalCardQueryResponseDTO queryResponseDTO = cardQueryResponse.getResult();

        PaymentConsumeRequestDTO payRequestDTO = new PaymentConsumeRequestDTO();
        payRequestDTO.setAppCode(appCode);
        payRequestDTO.setOrgCode(orgCode);
        payRequestDTO.setPayCode(payCode);
        payRequestDTO.setMer_cd(paymentSetting.getMerchantAccount());
        payRequestDTO.setMer_nm(paymentSetting.getOrgName());
        payRequestDTO.setOrderid(params.get("order_no"));
        payRequestDTO.setAccno(queryResponseDTO.getPersonal_account());
        payRequestDTO.setAccount(insuranceLoginName);
        payRequestDTO.setPassword(DigestUtils.md5Hex(paymentSetting.getSecretKey() + params.get("pay_password")).substring(8, 24));
        payRequestDTO.setCertiftp("00");
        payRequestDTO.setCertifid(queryResponseDTO.getId_number());
        payRequestDTO.setCustomernm(queryResponseDTO.getFull_name());
        payRequestDTO.setRcvlnst(queryResponseDTO.getBank_account_open());
        payRequestDTO.setCardsn(queryResponseDTO.getBank_account());
        payRequestDTO.setIssudt(queryResponseDTO.getRelease_time());
        payRequestDTO.setCardexp(queryResponseDTO.getValid_time());
        payRequestDTO.setAmt(org.apache.commons.lang3.StringUtils.leftPad(params.get("pay_amount"), 12, '0'));
        payRequestDTO.setMark(params.get("desc"));
        logger.info("PayServiceImpl.hymedUnionPay.payRequestDTO -> {}", JSON.toJSONString(payRequestDTO));

        ResCommon<PaymentConsumeResponseDTO> payResponse = HymedService.getHyMedClient().consumePayment(payRequestDTO);
        logger.info("PayServiceImpl.hymedUnionPay.payResponse -> {}", JSON.toJSONString(payResponse));

        if (payResponse.isSuccess()) {
            PaymentConsumeResponseDTO payResponseDTO = payResponse.getResult();

            params.put("app_id", paymentSetting.getPayAppId());
            UnifiedPayNotifyMessage unifiedMessage = buildHyMedPayUnifiedMessage(params, payResponseDTO);
            notifyExecutor.execute(new PayNotifyWorker(unifiedMessage));

            HashMap<String, String> result = new HashMap<>(2);
            result.put("payment_deal_id", payResponseDTO.getTraceno());
            result.put("pay_time", payResponseDTO.getTracetm());

            return new ResponseObject().buildResultObject(result);
        }

        return new ResponseObject().buildResultCodeAndMessageAndResult(
                payResponse.getResultCode(),
                payResponse.getResultMessage(),
                payResponse.getResult()
        );
    }

    private ResponseObject alipayMedWapPay(Map<String, String> params)
            throws PaySettingNotFoundException, UnsupportedEncodingException, AlipayApiException {
        if (checkAlipayMedWapPayParameters(params)) return invalidPayParamsResponseObject();

        Map<String, String> payParamsMap = buildAlipayMedWapPayParameters(params);
        logger.info("PayServiceImpl.alipayMedWapPay.payParamsMap -> {}", JSON.toJSONString(payParamsMap));

        String payUrl = assembleAlipayMedicarePayUrl(payParamsMap);
        logger.info("PayServiceImpl.alipayMedWapPay.payUrl -> {}", payUrl);

        Map<String, String> result = new HashMap<>();
        result.put("pay_url", payUrl);

        return new ResponseObject().buildResultObject(result);
    }

    private UnifiedPayNotifyMessage buildHyMedPayUnifiedMessage(Map<String, String> params, PaymentConsumeResponseDTO responseDTO) {
        UnifiedPayNotifyMessage unifiedMessage = new UnifiedPayNotifyMessage();
        unifiedMessage.setTradeStatus(AlipayNotify.TradeStatus.TRADE_SUCCESS.toString());
        unifiedMessage.setAppId(params.get("app_id"));
        unifiedMessage.setOpenId(params.get("insurance_login_name"));
        unifiedMessage.setPayAmount(responseDTO.getAmt());
        unifiedMessage.setInsuranceAmount("0");
        unifiedMessage.setTotalAmount(responseDTO.getAmt());
        unifiedMessage.setOrderNo(params.get("order_no"));
        unifiedMessage.setTradeNo(responseDTO.getCt_orderid());
        unifiedMessage.setPayTime(DateUtils.dateToString(Calendar.getInstance().getTime()));

        MchData mchData = new MchData();
        String payCode = params.get("pay_code");
        mchData.setAppId(params.get("app_id"));
        mchData.setPayCode(payCode);
        mchData.setPayMode(String.valueOf(getPayModeByPayCode(payCode)));
        mchData.setTopic(params.get("topic"));
        mchData.setIsInsurance(Medicare.INSURANCE_MODE_NOPE);
        unifiedMessage.setMchData(mchData);

        return unifiedMessage;
    }

    private UnifiedPayNotifyMessage buildAlipayMedInfoUploadSyncUnifiedMessage(Map<String, String> params, AlipayMedInfoUploadResponseDTO responseDTO) {
        UnifiedPayNotifyMessage unifiedMessage = new UnifiedPayNotifyMessage();
        unifiedMessage.setTradeStatus(AlipayNotify.TradeStatus.TRADE_SUCCESS.toString());
        unifiedMessage.setAppId(params.get("app_id"));
        unifiedMessage.setOpenId(params.get("open_id"));
        unifiedMessage.setPayAmount("0");
        unifiedMessage.setInsuranceAmount("0");
        unifiedMessage.setTotalAmount("0");
        unifiedMessage.setOrderNo(params.get("order_no"));
        unifiedMessage.setTradeNo(String.valueOf(System.currentTimeMillis()));
        unifiedMessage.setPayTime(DateUtils.dateToString(responseDTO.getGmtPayment()));
        unifiedMessage.setMedicalContent(responseDTO.getResponseContent());

        MchData mchData = new MchData();
        String payCode = params.get("pay_code");
        mchData.setAppId(params.get("app_id"));
        mchData.setPayCode(payCode);
        mchData.setPayMode(String.valueOf(getPayModeByPayCode(payCode)));
        mchData.setTopic(params.get("topic"));
        mchData.setIsInsurance(Medicare.INSURANCE_MODE_YEP);
        unifiedMessage.setMchData(mchData);

        return unifiedMessage;
    }

}
